package com.egao.common.module.student.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.egao.common.core.exception.BusinessException;
import com.egao.common.core.web.JsonResult;
import com.egao.common.module.student.constants.StudentConstants;
import com.egao.common.module.student.entity.Student;
import com.egao.common.module.student.entity.StudentSignMajorRecord;
import com.egao.common.module.student.entity.StudentSignRecord;
import com.egao.common.module.student.entity.vo.StudentSignStatisticsCollegeVO;
import com.egao.common.module.student.mapper.StudentSignMajorRecordMapper;
import com.egao.common.module.student.service.StudentService;
import com.egao.common.module.student.service.StudentSignMajorRecordService;
import com.egao.common.module.student.service.StudentSignService;
import com.egao.common.module.system.entity.Year;
import com.egao.common.module.system.service.YearService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 专业就业率记录Service实现
 *
 * @author 陈龙
 * @since 2024年04月09日 13:58:25
 */
@Service
public class StudentSignMajorRecordServiceImpl
        extends ServiceImpl<StudentSignMajorRecordMapper, StudentSignMajorRecord>
        implements StudentSignMajorRecordService {

    @Autowired
    private StudentService studentService;
    @Autowired
    private StudentSignService studentSignService;
    @Autowired
    private YearService yearService;

    @Override
    public void recordStudentMajorSignRate(Integer year, String xl) {
        List<StudentSignStatisticsCollegeVO> studentList = studentService.majorStudentCount(year, xl);
        if (studentList.isEmpty()) {
            return;
        }

        List<StudentSignStatisticsCollegeVO> studentSignList = studentSignService.majorStudentSignCount(year, xl);
        if (studentSignList.isEmpty()) {
            return;
        }

        // 结果集装载专业名称、专业人数
        // 结果集加入统计为0的专业
        for (StudentSignStatisticsCollegeVO student : studentList) {
            if (StrUtil.isBlank(student.getMajorCode())) {
                continue;
            }
            boolean b = false;
            for (StudentSignStatisticsCollegeVO sign : studentSignList) {
                if (StrUtil.isBlank(sign.getMajorCode())) {
                    continue;
                }
                if (student.getCollegeCode().equals(sign.getCollegeCode()) && student.getMajorCode().equals(sign.getMajorCode())) {
                    sign.setCollegeName(student.getCollegeName());
                    sign.setMajorName(student.getMajorName());
                    sign.setStudentCount(student.getStudentCount());
                    b = true;
                }
            }
            if (!b) {
                studentSignList.add(new StudentSignStatisticsCollegeVO(
                        student.getCollegeName(),
                        student.getCollegeCode(),
                        student.getMajorCode(),
                        student.getMajorName(),
                        student.getStudentCount(),
                        student.getCollegeSort()));
            }
        }

        // 定向生算进签约率
        List<Student> dxList = studentService.list(new QueryWrapper<Student>()
                .select("COUNT(1) id, college_code, major_code")
                .eq("year_id", year)
                .eq("pyfs", StudentConstants.PYFS_DX)
                .and("1".equals(xl), d -> d.eq("xl", "31").or().eq("xl", "25"))
                .eq("2".equals(xl), "xl", "11")
                .eq("3".equals(xl), "xl", "01")
                .and("4".equals(xl), d -> d.eq("xl", "11").or().eq("xl", "01"))
                .groupBy("college_code")
                .groupBy("major_code")
        );
        for (StudentSignStatisticsCollegeVO sign : studentSignList) {
            for (Student student : dxList) {
                if (sign.getCollegeCode().equals(student.getCollegeCode()) && sign.getMajorCode().equals(student.getMajorCode())) {
                    sign.setStudentSignCount(sign.getStudentSignCount() + student.getId());
                    sign.setXyjyCount(sign.getXyjyCount() + student.getId());
                }
            }
        }

        // 合计参数
        String totalName = "合计";
        Integer totalStudent = 0;
        Integer totalStudentSign = 0;
        Integer totalXyjy = 0;
        Integer totalZzcy = 0;
        Integer totalLhjy = 0;
        Integer totalZyzy = 0;
        Integer totalSx = 0;
        Integer totalCgcj = 0;
        Integer totalDjy = 0;

        // 开始计算百分比
        String rate = "#.##%";
        for (StudentSignStatisticsCollegeVO item : studentSignList) {
            Integer studentCount = item.getStudentCount();
            Integer studentSignCount = item.getStudentSignCount();

            BigDecimal studentRateB = NumberUtil.div(studentSignCount, studentCount);
            String studentRate = NumberUtil.decimalFormat(rate, studentRateB);
            item.setStudentRate(studentRate);

            BigDecimal xyjyRateB = NumberUtil.div(item.getXyjyCount(), studentCount);
            String xyjyRate = NumberUtil.decimalFormat(rate, xyjyRateB);
            item.setXyjyRate(xyjyRate);

            BigDecimal zzcyRateB = NumberUtil.div(item.getZzcyCount(), studentCount);
            String zzcyRate = NumberUtil.decimalFormat(rate, zzcyRateB);
            item.setZzcyRate(zzcyRate);

            BigDecimal lhjyRateB = NumberUtil.div(item.getLhjyCount(), studentCount);
            String lhjyRate = NumberUtil.decimalFormat(rate, lhjyRateB);
            item.setLhjyRate(lhjyRate);

            BigDecimal zyzyRateB = NumberUtil.div(item.getZyzyCount(), studentCount);
            String zyzyRate = NumberUtil.decimalFormat(rate, zyzyRateB);
            item.setZyzyRate(zyzyRate);

            BigDecimal sxRateB = NumberUtil.div(item.getSxCount(), studentCount);
            String sxRate = NumberUtil.decimalFormat(rate, sxRateB);
            item.setSxRate(sxRate);

            BigDecimal cgcjRateB = NumberUtil.div(item.getCgcjCount(), studentCount);
            String cgcjRate = NumberUtil.decimalFormat(rate, cgcjRateB);
            item.setCgcjRate(cgcjRate);

            Integer djyCount = studentCount - studentSignCount;
            BigDecimal djyRateB = NumberUtil.div(djyCount, studentCount);
            String djyRate = NumberUtil.decimalFormat(rate, djyRateB);
            item.setDjyRate(djyRate);
            item.setDjyCount(djyCount);

            totalStudent += studentCount;
            totalStudentSign += studentSignCount;
            totalXyjy += item.getXyjyCount();
            totalZzcy += item.getZzcyCount();
            totalLhjy += item.getLhjyCount();
            totalZyzy += item.getZyzyCount();
            totalSx += item.getSxCount();
            totalCgcj += item.getCgcjCount();
            totalDjy += item.getDjyCount();
        }

        studentSignList = studentSignList.stream().sorted(Comparator.comparing(StudentSignStatisticsCollegeVO::getCollegeSort)).collect(Collectors.toList());

        // 合计
        StudentSignStatisticsCollegeVO total = new StudentSignStatisticsCollegeVO();
        total.setCollegeCode("0");
        total.setCollegeName(totalName);
        total.setMajorCode("0");
        total.setMajorName(totalName);
        total.setStudentCount(totalStudent);
        total.setStudentSignCount(totalStudentSign);

        BigDecimal studentRateB = NumberUtil.div(totalStudentSign, totalStudent);
        String studentRate = NumberUtil.decimalFormat(rate, studentRateB);
        total.setStudentRate(studentRate);

        BigDecimal xyjyRateB = NumberUtil.div(totalXyjy, totalStudent);
        String xyjyRate = NumberUtil.decimalFormat(rate, xyjyRateB);
        total.setXyjyRate(xyjyRate);
        total.setXyjyCount(totalXyjy);

        BigDecimal zzcyRateB = NumberUtil.div(totalZzcy, totalStudent);
        String zzcyRate = NumberUtil.decimalFormat(rate, zzcyRateB);
        total.setZzcyRate(zzcyRate);
        total.setZzcyCount(totalZzcy);

        BigDecimal lhjyRateB = NumberUtil.div(totalLhjy, totalStudent);
        String lhjyRate = NumberUtil.decimalFormat(rate, lhjyRateB);
        total.setLhjyRate(lhjyRate);
        total.setLhjyCount(totalLhjy);

        BigDecimal zyzyRateB = NumberUtil.div(totalZyzy, totalStudent);
        String zyzyRate = NumberUtil.decimalFormat(rate, zyzyRateB);
        total.setZyzyRate(zyzyRate);
        total.setZyzyCount(totalZyzy);

        BigDecimal sxRateB = NumberUtil.div(totalSx, totalStudent);
        String sxRate = NumberUtil.decimalFormat(rate, sxRateB);
        total.setSxRate(sxRate);
        total.setSxCount(totalSx);

        BigDecimal cgcjRateB = NumberUtil.div(totalCgcj, totalStudent);
        String cgcjRate = NumberUtil.decimalFormat(rate, cgcjRateB);
        total.setCgcjRate(cgcjRate);
        total.setCgcjCount(totalCgcj);

        BigDecimal djyRateB = NumberUtil.div(totalDjy, totalStudent);
        String djyRate = NumberUtil.decimalFormat(rate, djyRateB);
        total.setDjyRate(djyRate);
        total.setDjyCount(totalDjy);

        studentSignList.add(0, total);

        // 数据转换 studentSignList -> StudentSignMajorRecordList
        List<StudentSignMajorRecord> studentSignMajorRecordList = new ArrayList<>();
        int sort = 0;
        for (StudentSignStatisticsCollegeVO item : studentSignList) {
            StudentSignMajorRecord studentSignMajorRecord = new StudentSignMajorRecord();

            studentSignMajorRecord.setYear(year);
            studentSignMajorRecord.setXl(xl);
            studentSignMajorRecord.setMajorName(item.getMajorName());
            studentSignMajorRecord.setStudentCount(item.getStudentCount());
            studentSignMajorRecord.setCollegeName(item.getCollegeName());
            studentSignMajorRecord.setStudentRate(item.getStudentRate());
            studentSignMajorRecord.setStudentSignCount(item.getStudentSignCount());
            studentSignMajorRecord.setXyjyCount(item.getXyjyCount());
            studentSignMajorRecord.setXyjyRate(item.getXyjyRate());
            studentSignMajorRecord.setLhjyCount(item.getLhjyCount());
            studentSignMajorRecord.setLhjyRate(item.getLhjyRate());
            studentSignMajorRecord.setSxCount(item.getSxCount());
            studentSignMajorRecord.setSxRate(item.getSxRate());
            studentSignMajorRecord.setCgcjCount(item.getCgcjCount());
            studentSignMajorRecord.setCgcjRate(item.getCgcjRate());
            studentSignMajorRecord.setZzcyCount(item.getZzcyCount());
            studentSignMajorRecord.setZzcyRate(item.getZzcyRate());
            studentSignMajorRecord.setZyzyCount(item.getZyzyCount());
            studentSignMajorRecord.setZyzyRate(item.getZyzyRate());
            studentSignMajorRecord.setDjyCount(item.getDjyCount());
            studentSignMajorRecord.setDjyRate(item.getDjyRate());
            studentSignMajorRecord.setSort(sort++);

            studentSignMajorRecordList.add(studentSignMajorRecord);
        }

        // 判断当天是否有对应学历的数据，如果有就删除原有的数据
        Date createTime = new Date();
        DateTime beginOfDay = DateUtil.beginOfDay(createTime);
        DateTime endOfDay = DateUtil.endOfDay(createTime);
        StudentSignMajorRecord one = this.baseMapper.selectOne(
                new LambdaQueryWrapper<>(StudentSignMajorRecord.class)
                        .eq(StudentSignMajorRecord::getXl, xl)
                        .eq(StudentSignMajorRecord::getYear, year)
                        .between(StudentSignMajorRecord::getCreateTime, beginOfDay, endOfDay)
                        .orderByDesc(StudentSignMajorRecord::getCreateTime)
                        .last("limit 1")
        );
        if (!Objects.isNull(one)) {
            int delete = this.baseMapper.delete(
                    new LambdaQueryWrapper<>(StudentSignMajorRecord.class)
                            .eq(StudentSignMajorRecord::getXl, xl)
                            .between(StudentSignMajorRecord::getCreateTime, beginOfDay, endOfDay));
            if (delete <= 0) {
                throw new RuntimeException("删除重复专业就业率记录失败");
            }
        }

        // 保存
        if (!this.saveBatch(studentSignMajorRecordList)) {
            throw new RuntimeException("保存专业就业率记录失败");
        }


    }

    @Override
    public List<StudentSignMajorRecord> getStudentMajorSignRateRecord(Integer year, String xl, Date createTime) {
        // 如果输入时间为空，就获取最近一组数据
        if (Objects.isNull(createTime)) {
            // 最近一条的时间
            StudentSignMajorRecord studentSignMajorRecord = this.baseMapper.selectOne(
                    new LambdaQueryWrapper<>(StudentSignMajorRecord.class)
                            .orderByDesc(StudentSignMajorRecord::getCreateTime)
                            .last("limit 1"));
            if (Objects.isNull(studentSignMajorRecord)) {
                throw new BusinessException("暂无数据");
            }
            createTime = studentSignMajorRecord.getCreateTime();
        }
        // 查询这一天内的数据
        DateTime beginOfDay = DateUtil.beginOfDay(createTime);
        DateTime dateTime = DateUtil.endOfDay(createTime);

        return this.baseMapper.selectList(
                new LambdaQueryWrapper<StudentSignMajorRecord>()
                        .eq(StudentSignMajorRecord::getYear, year)
                        .eq(StudentSignMajorRecord::getXl, xl)
                        .between(StudentSignMajorRecord::getCreateTime, beginOfDay, dateTime)
                        .orderByAsc(StudentSignMajorRecord::getSort)
        );
    }
}
